Configuring the Parser with a configuration file

For every project, you can specify a file containing directives for the Parser. See also Parser configuration file Here, we assume that you are using the same configuration file for multiple projects.
Specifying the location of your Parser configuration file

In any open SNiFF+ tool, choose Tools > Project Editor to open the Project Editor.
In the Project Tree, checkmark the projects for which you you will be using the Parser configuration file.
Check out the PDFs of the checkmarked projects.
Choose Project > Attributes of Checkmarked Projects....
Select the Parser node.

In the Parser view

Specify the location of the Parser configuration file in the Parser Configuration File(s) field.
Select check box to the right of the Parser Configuration File(s) field, this will make the attribute applicable to all Projects in the list on the right..
Press the Set for All button.
Press the OK button to close the Group Project Attributes dialog.

In the Project Editor

Save all modified projects.
In order for your changes to take effect, you must also reparse the projects that you just modified. In the Project Tree, make sure the projects for which you've enabled full preprocessing are still checkmarked.
Choose Project > Force Reparse.

Parser configuration file
The Parser configuration file contains special configuration instructions for the Parser. The location of the file is specified by the Parser Configuration File(s) attribute in the Parser view of the Project Attributes and the Preferences.
The Parser considers the configuration file both when preprocessing is enabled and when it is disabled. If preprocessing is enabled, the directives in the configuration file are evaluated and executed after preprocessing.
Parser directives and modifiers
The configuration file can contain the following directives: (The expressions in square brackets ([ ]) are modifiers you can use with directives, see Modifiers for details.)

Directives | Description
ignore string string [leading] [trailing] [anywhere] [whole] | The Parser ignores words that match string in the source code. If no option is specified only whole words are matched.
ignore from string1 to string2 [exclusive] [instring] [incomment] [leading] [trailing] [anywere] | The Parser ignores anything between the two strings.
ignore line string [begin] [instring] [incomment] [leading] [trailing] [anywere] | The Parser ignores lines that contain string.
define symbol | The Parser resolves #ifdef and #if directives containing symbol.
undefine symbol | The Parser resolves #ifndef , #if ! defined and else branches of #if directives containing symbol.

| Note
| All preprocessor directives (e.g., -I , -L , -U ) except for -D can also be used in the Parser configuration file. cpp syntax applies to all directives.

In addition to any ASCII character, string can contain

\n , \t and \nnn , where \nnn is an octal number. The following table describes the modifiers you can use:

Modifiers | Description
[leading] | Means that string identifies a leading part of a word.
[trailing] | Means that string identifies a trailing part of a word.
[anywere] | Means that string is matched anywhere in a word.
[whole] | Causes the Parser to ignore the whole word, even if just a part of the word is matched by string. Note: In order to use this modifier, you also have to use the [anywere] modifier.
[exclusive] | Means that string2 is not ignored. If the option is not present, the Parser ignores everything between string1 and string2, inclusively.
[instring] | Means that the Parser also looks for string in strings delimited by quotes ( " or ').
[incomment] | Means that the Parser also looks for string in comments delimited by // or /*...*/ .
[begin] | Causes the Parser to ignore only lines beginning with string. If this option is not present, the location of string is not important.

# Example ignore strings file |
# |
ignore string VIRTUAL | # for NIHCL
ignore string _C_ARG1 | # for the License project
ignore from EXEC to ; | # ignore all embedded SQL statements
define UNIX | # resolve ifdefs for UNIX

Examples -- Parser configuration
Strings, lines and constructs to be ignored by the Parser
The Parser can be configured to ignore strings, anything between two strings and lines containing a certain string.
Example of ignoring strings
The

VIRTUAL macro is used in the NIH class library in class definitions like this:
class A : public VIRTUAL B
{ ... };
The VIRTUAL string confuses the Parser since the C++ syntax requires that a class name must follow the keyword public .
To solve the above problem without doing full preprocessing:

- Tell the Parser to ignore the

VIRTUAL string:
ignore string VIRTUAL
IMPORTANT: All affected projects must be reparsed after the configuration file has been changed.
Resolving #ifdef and #if directives
Some class libraries use the preprocessor directives #ifdef or #if to modify the code in a way that confuses the Parser. In such cases the Parser configuration file allows you to selectively resolve #ifdef or #if directives without doing full preprocessing.
Scenario 1: resolving different class definitions for the same class
#ifdef UNIX
class someClass : unixBaseClass
#else
class someClass : otherBaseClass
#endif
{ ... };
Since SNiFF+ normally parses the file without resolving #ifdef statements, it reads two class definition headers and just one actual definition.
To solve this problem, you have two possibilities:

- add the following line to the Parser configuration file:

define UNIX
This tells the Parser to ignore the line between the #else and the #endif directives.
- add the following line to the Parser configuration file:
undefine UNIX
The Parser will ignore the line between #ifdef and #else .
Scenario 2: resolving unbalanced braces
#ifdef HUGE_INT
for (int i=0; i<MAXVAL; i++) {
#else
for (long i=0; i<MAXVAL; i++) {
#endif
... }
Since SNiFF+ normally parses files without resolving #ifdef statements, it reads two opening and only one closing brace.
To solve this problem, you have two possibilities:

- add the following line to the Parser configuration file:

define HUGE_INT
- remove the opening brace from the two
for lines and put it after the #endif directive.
Scenario 3: resolving complex #if directives
#if defined (UNIX) || defined (VMS)
class someClass : unixBaseClass
#else
class someClass : otherBaseClass
#endif
{ ... };
The expression after the #if directive will be evaluated only if it contains the || , && , ! (logical negation), defined operator and parentheses for grouping. If the expression contains other operators or a defined operator with an identifier that does not appear in the Parser configuration file, the #if is not resolved (i.e., both branches are parsed).
For example, assuming that your configuration file contains the following:
define AAA
undefine BBB
Then:

AAA is defined
BBB is not defined
CCC is neither defined nor undefined
in the preprocessor call. Then, from the following source code, only a , d,e and f will appear in the Symbol Table.
#if defined(AAA)
int a;
#else
int b;
#endif
#if defined(AAA) && defined(BBB)
int c;
#else
int d;
#endif
#if defined(CCC)
int e;
#else
int f;
#endif